﻿/****************************** Module Header ******************************\
 * Module Name:  mxType.cs
 * Module Version:  1.0.0 (2012-11-19)
 * Copyright (c) AnyEB.Com (14507247@qq.com)
 * 
 * This class is used to extension collection instance's method.  It supplies 
 * useful extension methods, such as ToString(), FetchString() and so on.
 * 
 * This source is subject to the GPL License.
 * See http://www.gnu.org/licenses/gpl.html.
 * All other rights reserved.
 * 
 * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
 * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
\***************************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace UCL
{
    public static class mxType
    {
        /// <summary>
        /// CsharpType转DbType
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public static DbType ToDbType(this Type t)
        {
            DbType dbt;
            return Enum.TryParse<DbType>(t.Name, out dbt) ? dbt : DbType.Object;
        }

        /// <summary>
        /// DbType转CsharpType
        /// </summary>
        /// <param name="dbType"></param>
        /// <returns></returns>
        public static Type ToType(this DbType dbType)
        {
            Type toReturn = typeof(DBNull);

            switch (dbType)
            {
                case DbType.UInt64:
                    toReturn = typeof(UInt64);
                    break;
                case DbType.Int64:
                    toReturn = typeof(Int64);
                    break;
                case DbType.Int32:
                    toReturn = typeof(Int32);
                    break;
                case DbType.UInt32:
                    toReturn = typeof(UInt32);
                    break;
                case DbType.Single:
                    toReturn = typeof(float);
                    break;
                case DbType.Date:
                case DbType.DateTime:
                case DbType.Time:
                    toReturn = typeof(DateTime);
                    break;
                case DbType.String:
                case DbType.StringFixedLength:
                case DbType.AnsiString:
                case DbType.AnsiStringFixedLength:
                    toReturn = typeof(string);
                    break;
                case DbType.UInt16:
                    toReturn = typeof(UInt16);
                    break;
                case DbType.Int16:
                    toReturn = typeof(Int16);
                    break;
                case DbType.SByte:
                    toReturn = typeof(byte);
                    break;
                case DbType.Object:
                    toReturn = typeof(object);
                    break;
                case DbType.VarNumeric:
                case DbType.Decimal:
                    toReturn = typeof(decimal);
                    break;
                case DbType.Currency:
                    toReturn = typeof(double);
                    break;
                case DbType.Binary:
                    toReturn = typeof(byte[]);
                    break;
                case DbType.Double:
                    toReturn = typeof(Double);
                    break;
                case DbType.Guid:
                    toReturn = typeof(Guid);
                    break;
                case DbType.Boolean:
                    toReturn = typeof(bool);
                    break;
            }
            return toReturn;
        }

        /// <summary>
        /// SqlDbType转CsharpType
        /// </summary>
        /// <param name="sqlType"></param>
        /// <returns></returns>
        public static Type ToType(this SqlDbType sqlType)
        {
            switch (sqlType)
            {
                case SqlDbType.VarChar:
                case SqlDbType.NVarChar:
                case SqlDbType.Text:
                case SqlDbType.NText:
                case SqlDbType.Char:
                case SqlDbType.NChar:
                    return typeof(String);

                case SqlDbType.UniqueIdentifier:
                    return typeof(Guid);

                case SqlDbType.Bit:
                    return typeof(Boolean);

                case SqlDbType.Decimal:
                case SqlDbType.Money:
                case SqlDbType.SmallMoney:
                    return typeof(Decimal);

                case SqlDbType.Int:
                    return typeof(Int32);

                case SqlDbType.DateTime:
                case SqlDbType.SmallDateTime:
                    return typeof(DateTime);

                case SqlDbType.SmallInt:
                    return typeof(Int16);

                case SqlDbType.Float:
                    return typeof(Double);

                case SqlDbType.Timestamp:
                case SqlDbType.Image:
                case SqlDbType.Binary:
                case SqlDbType.VarBinary:
                    return typeof(byte[]);

                case SqlDbType.TinyInt:
                    return typeof(Byte);

                case SqlDbType.Xml:
                    return typeof(Object);

                case SqlDbType.BigInt:
                    return typeof(Int64);

                case SqlDbType.Real:
                    return typeof(Single);

                case SqlDbType.Variant:
                case SqlDbType.Udt://自定义的数据类型
                    return typeof(Object);

                default:
                    return null;
            }
        }

        /// <summary>
        /// 判断值类型是否是指定类型的可空类型
        /// <para>2012-11-29</para>
        /// <para>如：return pi.PropertyType.IsGType&lt;int&gt;();</para>
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public static bool IsGType<T>(this Type t) where T : struct
        {
            return t == typeof(T) || t == typeof(Nullable<T>);
        }

        /// <summary>
        /// 获取可空类型的非空值
        /// <para>如：return user.Sex.NotNull&lt;short&gt;(0);</para>
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <param name="defv"></param>
        /// <returns></returns>
        /// <remarks>2012-12-7</remarks>
        public static T NotNull<T>(this T? t,T defv) where T : struct
        {
            return t.HasValue ? t.Value : defv;
        }

        /// <summary>
        /// 判断值是否在集合中
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        /// <remarks>2014-2-24 由mxString迁移并改为泛型方法</remarks>
        public static bool IsIn<T>(this T t, params T[] args)
        {
            return args.Contains(t);
        }

    }
}
